package cn.skcks.springboot06security.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	// 授权
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 请求授权规则
		http.authorizeRequests()
				.antMatchers("/").permitAll()

				.antMatchers("/level1/**").hasRole("vip")
				.antMatchers("/level/1/**").hasRole("vip")

				.antMatchers("/level2/**").hasRole("vip2")
				.antMatchers("/level/2/**").hasRole("vip2")

				.antMatchers("/level3/**").hasRole("vip3")
				.antMatchers("/level/3/**").hasRole("vip3");

		// 没有权限 默认跳到登录页
		http.formLogin()
				// 指定自定义的登录页
				.loginPage("/toLogin")
				// 表单请求处理地址
				.loginProcessingUrl("/login")
				// 自定义 用户名 表单字段名
				.usernameParameter("user")
				// 自定义 密码 表单字段名
				.passwordParameter("pwd");

		// 关闭 防 CSRF 跨站请求伪造
		http.csrf().disable();

		// 开启注销
		http.logout()
				// 注销后返回首页
				.logoutSuccessUrl("/");

		// 开启 rememberMe, 默认保存 14天
		http.rememberMe()
				// 自定义 rememberMe 表单字段名
				.rememberMeParameter("remember");
	}

	// 认证
	// SpringSecurity 5.0+ 新增了许多加密方法
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		String password = new BCryptPasswordEncoder().encode("12341234");

		auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
				.withUser("admin").password(password).roles("vip", "vip2", "vip3").and()
				.withUser("user1").password(password).roles("vip").and()
				.withUser("user2").password(password).roles("vip2").and()
				.withUser("user3").password(password).roles("vip3");
	}
}